﻿using ELTE.TFEG.Hough.EventHandling;
using ELTE.TFEG.Hough.Wpf.Classes;
using ELTE.TFEG.Hough.Wpf.Controls;
using ELTE.TFEG.ImageTransform;
using ELTE.TFEG.ImageTransform.EventHandling;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ELTE.TFEG.Hough.Wpf
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ImageFileManager imageManager = new ImageFileManager();

        MainViewModel ViewModel = new MainViewModel();


        int cubeSize = 300;

        public MainWindow()
        {
            InitializeComponent();
            InitCommmands();
            LoadImages();
        }

        private void InitCommmands()
        {
            this.ViewModel.NextStep = new DelegateCommand(o => NextStep());

            this.ViewModel.TransformSelectionChange = new DelegateCommand(o => TransformModeSelectionChanged());

            this.ViewModel.GenerateHough = new DelegateCommand(o => GenerateHough());

            this.ViewModel.SaveHoughImages = new DelegateCommand(o => SaveHoughImages());

            this.DataContext = this.ViewModel;
        }

        private void LoadImages()
        {
            //1. get the list of images available
            string folderPath = Properties.Settings.Default.ImageFolderPath;
            List<string> availableImages = imageManager.GetImageFilesInFolders(folderPath, Constants.Extensions, Constants.Suffixes);
            availableImages.ForEach(img => this.stackAvailableImages.Children.Add(new ZoomableImageControl(img, cubeSize, cubeSize)));
            foreach (ZoomableImageControl img in this.stackAvailableImages.Children)
            {
                img.CalculateScale();
                img.ViewModel.SelectChanged += ViewModel_SelectChanged;
            }
        }

        void ViewModel_SelectChanged(object sender, EventArgs e)
        {
            ZoomableImageControl senderAs = sender as ZoomableImageControl;
            if (senderAs != null)
            {
                //check for other items in the available images' children
                foreach (ZoomableImageControl img in this.stackAvailableImages.Children)
                {
                    if (img.IsSelected && !img.Equals(senderAs))
                    {
                        img.ToggleSelect(false);
                    }
                }
                this.TransformModeSelectionChanged();

                //check for the other steps
                if (this.stackEdgeDetectedImages.Children.Count > 0)
                {
                    this.stackEdgeDetectedImages.Children.Clear();
                }
                if (this.stackHoughImages.Children.Count > 0)
                {
                    this.stackHoughImages.Children.Clear();
                }
                
            }
        }

        void NextStep()
        {
            //generate the edge detected images
            this.imageManager.GetEdgeDetectedImages(GetSelectedImage(this.stackAvailableImages)).ForEach(img =>
            {
                ZoomableImageControl ctrl = new ZoomableImageControl(img, cubeSize, cubeSize);
                this.stackEdgeDetectedImages.Children.Add(ctrl);
                ctrl.ViewModel.SelectChanged += EdgeDetectedImage_SelectChanged;
            });
        }

        private void EdgeDetectedImage_SelectChanged(object sender, EventArgs e)
        {
            ZoomableImageControl ctrl = sender as ZoomableImageControl;
            if (ctrl != null)
            {
                //check if there is any selected image
                this.btnGenerateHough.IsEnabled = HaveSelectedAnImage(this.stackEdgeDetectedImages);
                foreach (ZoomableImageControl zCtrl in this.stackEdgeDetectedImages.Children)
                {
                    if (zCtrl.IsSelected && zCtrl != ctrl)
                    {
                        zCtrl.ToggleSelect(false);
                    }
                }
            }
        }

        private bool HaveSelectedTransformOptions()
        {
            bool selectedAny = false;
            foreach (var chk in this.lstTransformOptions.Items)
            {
                if (chk.GetType() == typeof(CheckBox))
                {
                    if (((CheckBox)chk).IsChecked.HasValue && ((CheckBox)chk).IsChecked.Value)
                    {
                        selectedAny = true;
                        break;
                    }
                }
            }
            return selectedAny;
        }

        private Bitmap GetSelectedImage(StackPanel stackPanel)
        {
            Bitmap src = null;
            foreach (ZoomableImageControl ctrl in stackPanel.Children)
            {
                if (ctrl.IsSelected)
                {
                    src = ctrl.BitmapSource;
                }
            }
            return src;
        }

        private bool HaveSelectedAnImage(StackPanel stackPanel)
        {
            bool result = false;
            foreach (ZoomableImageControl ctrl in stackPanel.Children)
            {
                if (ctrl.IsSelected)
                {
                    result = true;
                    break;
                }
            }
            return result;
        }

        void TransformModeSelectionChanged()
        {

            bool selectedAnyOption = HaveSelectedTransformOptions();
            bool selectedAnyPicture = HaveSelectedAnImage(this.stackAvailableImages);
            if (selectedAnyOption && selectedAnyPicture)
            {
                if (!this.btnNextStep.IsEnabled)
                {
                    this.btnNextStep.IsEnabled = true;
                }
            }
            else
            {
                if (this.btnNextStep.IsEnabled)
                {
                    this.btnNextStep.IsEnabled = false;
                }
            }
        }

        void GenerateHough()
        {
            this.btnGenerateHough.IsEnabled = false;
            List<HoughTransformMode> selection = new List<HoughTransformMode>();
            if (this.chkCircles.IsChecked.HasValue && this.chkCircles.IsChecked.Value)
            {
                selection.Add(HoughTransformMode.HoughCircle);
            }
            if (this.chkLines.IsChecked.HasValue && this.chkLines.IsChecked.Value)
            {
                selection.Add(HoughTransformMode.HoughLine);
            }
            if (this.chkLineSegments.IsChecked.HasValue && this.chkLineSegments.IsChecked.Value)
            {
                selection.Add(HoughTransformMode.HoughLineSegment);
            }

            int percentage = this.nudPercentage.Value.HasValue ? this.nudPercentage.Value.Value : 50;
            int radius = this.nudRadius.Value.HasValue ? this.nudRadius.Value.Value : 30;
            List<Bitmap> houghImages = imageManager
                .GetHough(
                    GetSelectedImage(this.stackEdgeDetectedImages),
                    selection,
                    percentage,
                    chkShouldDistinct.IsChecked.HasValue ? chkShouldDistinct.IsChecked.Value : false,
                    chkShouldTraceDown.IsChecked.HasValue? chkShouldTraceDown.IsChecked.Value : false,
                    radius);

            this.stackHoughImages.Children.Clear();
            System.Threading.Thread.Sleep(500);
            houghImages.ForEach(img => 
                {
                    ZoomableImageControl ctrl = new ZoomableImageControl(img, cubeSize, cubeSize);
                    ctrl.ViewModel.SelectChanged += HoughImage_SelectChanged;
                    this.stackHoughImages.Children.Add(ctrl);
                }
                );
            this.btnGenerateHough.IsEnabled = true;
        }

        void HoughImage_SelectChanged(object sender, EventArgs e)
        {
            ZoomableImageControl zSender = sender as ZoomableImageControl;
            foreach (ZoomableImageControl ctrl in this.stackHoughImages.Children)
            {
                if (ctrl.IsSelected && !ctrl.Equals(zSender))
                {
                    ctrl.ToggleSelect(false);
                }
            }

            this.btnSaveImages.IsEnabled = HaveSelectedAnImage(this.stackHoughImages);
            
        }

        void SaveHoughImages()
        {
            try
            {
                SaveFileDialog dialog = new SaveFileDialog { Filter = "Image Files (*.png)|**.png" };
                bool? result = dialog.ShowDialog();
                if (result.HasValue && result.Value)
                {
                    Bitmap bmp = GetSelectedImage(this.stackHoughImages);
                    if (bmp != null)
                    {
                        bmp.Save(dialog.FileName);
                        MessageBox.Show("Sikeres mentés");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            
        }
    }
}
